home *** CD-ROM | disk | FTP | other *** search
- /*
- REMOVE -- February 26, 1997
- Simple Nomad -- Nomad Mobile Research Centre
-
- Universal utmp, wtmp, and lastlog editor. Actually
- removes, doesn't leave holes...
-
- Compile "cc -o remove remove.c -DGENERIC" and run
- as root. Use -DAIX instead of -DGENERIC for an AIX
- machine. Use -DSCO instead of -DGENERIC for a SCO
- machine.
- */
-
- #include <stdio.h>
- #include <utmp.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <fcntl.h>
- #ifndef AIX
- #include <lastlog.h>
- #else
- #include <login.h>
- #endif
- #include <pwd.h>
-
- #ifdef AIX
- #define WTMP "/var/adm/wtmp"
- #define UTMP "/etc/utmp"
- #define LASTLOG "/etc/security/lastlog" /* Not a binary file in AIX, so */
- /* handled a bit differently. */
- char LogParam[7][30]=
- {
- "time_last_login=","tty_last_login=","host_last_login=",
- "unsuccessful_login_count=","time_last_unsuccessful_login=",
- "tty_last_unsuccessful_login=","host_last_unsuccessful_login="
- };
- #endif
- #ifdef SCO
- #define WTMP "/etc/wtmp" /* wtmp was here on the SCO box I accessed */
- #define UTMP "/var/adm/utmp"
- #define LASTLOG "/var/adm/lastlog"
- #endif
- #ifdef GENERIC /* Should work with Linux, IRIX, Digital Unix, BSDs, etc */
- #define WTMP "/var/adm/wtmp"
- #define UTMP "/var/adm/utmp"
- #define LASTLOG "/var/adm/lastlog"
- #endif
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- int cleanWtmp(char *,int);
- int cleanUtmp(char *,int);
- int cleanLastlog(char *);
- int getCount(char *,char *);
- char line[10];
- int killem, firstcnt, t;
-
- if(argc!=2)
- {
- printf("Usage: %s acct\n",argv[0]);
- exit(0);
- }
- firstcnt=getCount(WTMP,argv[1]); /* Get an initial count */
- printf("\nREMOVE by Simple Nomad\nNomad Mobile Research Centre (c) 1997\n\n");
- printf("Found %d record(s) for user %s\n",firstcnt,argv[1]);
- printf("Will attempt a lastlog cleanup by default.\n\n");
- printf("# - remove last # records from utmp/wtmp\n");
- printf("a - remove (a)ll records from utmp/wtmp\n");
- printf("q - (q)uit program\n\n");
- printf("Enter selection -> ");
- gets(line);
- if(line[0]==0x51 || line[0]==0x71) exit(0);
- if(line[0]==0x41 || line[0]==0x61) killem=firstcnt;
- else killem=atoi(line);
- if (killem>firstcnt)
- {
- printf("You cannot delete %d records if only %d exist.\n",killem,firstcnt);
- exit(-1);
- }
- t=cleanWtmp(argv[1],killem); /* Now to clean up utmp and wtmp */
- if (t==1) {
- printf("Trouble cleaning up %s.\n",WTMP);
- exit(-1);
- } else printf("REMOVE cleaned up %d record(s) from %s\n",killem,WTMP);
- t=cleanUtmp(argv[1],killem);
- if (t==1) {
- printf("Trouble cleaning up %s.\n",UTMP);
- exit(-1);
- } else printf("REMOVE cleaned up %d record(s) from %s\n",killem,UTMP);
- t=cleanLastlog(argv[1]); /* Make our attempt at lastlog */
- if (t==1) {
- printf("Trouble cleaning up %s.\n",LASTLOG); exit(-1);
- }
- printf("REMOVE cleaned up %s\n",LASTLOG);
- } /* end main */
-
- int getCount(fname,acct) /* Go check wtmp and find out how many records */
- char *fname, *acct;
- {
- struct utmp utmp_ent;
- int f,cnt=0;
-
- if((f=open(fname,O_RDWR))>=0){
- while(read(f,&utmp_ent,sizeof(utmp_ent)))if(!strncmp(utmp_ent.ut_name, acct,strlen(acct)))cnt++;
- }
- close(f);
- return(cnt);
- } /* end getCount */
-
- int cleanWtmp(acct,killem)
- char *acct;
- int killem;
- {
- struct utmp utmp_ent;
- int fd,count=0;
- if((fd=open(WTMP,O_RDWR))>=0){
- while(read(fd,&utmp_ent,sizeof(utmp_ent)))if(!strncmp(utmp_ent.ut_name,acct,strlen(acct)))count++;
- lseek(fd,0,SEEK_SET);
- while(read(fd,&utmp_ent,sizeof(utmp_ent))&&killem){
- if(!strncmp(utmp_ent.ut_name,acct,strlen(acct))){
- count--;
- if(count+1<=killem){
- bzero((char *)&utmp_ent,sizeof(utmp_ent));
- lseek(fd,-(sizeof(utmp_ent)),SEEK_CUR);
- write(fd,&utmp_ent,sizeof(utmp_ent));
- killem--;
- }
- }
- }
- close(fd);
- }
- else return(1);
- } /* end cleanWtmp */
-
- int cleanUtmp(acct,killem)
- char *acct;
- int killem;
- {
- struct utmp utmp_ent;
- int fd;
- if((fd=open(UTMP,O_RDWR))>=0){
- lseek(fd,0,SEEK_SET);
- while(read(fd,&utmp_ent,sizeof(utmp_ent))&&killem){
- if(!strncmp(utmp_ent.ut_name,acct,strlen(acct))){
- if(killem>0){
- bzero((char *)&utmp_ent,sizeof(utmp_ent));
- lseek(fd,-(sizeof(utmp_ent)),SEEK_CUR);
- write(fd,&utmp_ent,sizeof(utmp_ent));
- killem--;
- }
- }
- }
- close(fd);
- }
- else return(1);
- } /* end cleanUtmp */
-
- int cleanLastlog(acct) /* The lastlog subroutine */
- char *acct;
- {
- #ifdef AIX /* Quite a kludge for AIX, but what the fuck it works */
- int t,i;
- char entry[200];
- for (i=0;i<7;i++)
- {
- sprintf(entry,"chsec -f %s -s %s -a %s>/dev/null",LASTLOG,acct,LogParam[i]);
- t=system(entry);
- printf("Return code for %s is %d\n",LogParam[i],t);
- }
- #else /* Normal binary lastlog cleanup */
- struct passwd *pwd;
- struct lastlog logit;
- int f;
- if((pwd=getpwnam(acct))){
- if((f=open(LASTLOG,O_RDWR))>=0){
- lseek(f,(long)pwd->pw_uid*sizeof(struct lastlog),0);
- bzero((char *)&logit,sizeof(logit));
- write(f,(char *)&logit,sizeof(logit));
- close(f);
- }
- }
- else return(1);
- #endif
- } /* end cleanLastlog */
-